<!--
  增删改查示例
  @author 邵鹏坤 2022年9月22日
  1 功能解析：
    1.1 列表展示
      1.1.1 数据源：示例
        tableData：Array<{
          name:'张三'，
          height:180，
          weight:200，
          birth:’2022-9-22 21：02：30，
          ...
        }>
      1.1.2 列属性
        columns: Array<{
          // 用于绑定data里的数据字段名 必选
          key: string
          // 用于渲染在列头上的列明 必选
          listed: string
          // 列宽度px 如果没有就自适应 可选
          width?: number
        }>
    1.2 ...
  2 数据源：
-->
<template>
  <div class="table-container" :style="tableStyle">
    <table :class="un.e()">
      <WinHeader @changeWidth="changeWidth"> </WinHeader>
      <WinRow
        v-for="(row, index) in props.data"
        :key="row[keyName]"
        :rowData="row"
        :index="index"
        @click.right="rightMenu($event, row)"
      ></WinRow>
    </table>
    <Transition name="scale">
      <MouseDialog
        ref="mouseDialog"
        v-if="mouseMenu"
        :mouseMenu="mouseMenu"
        width="160px"
        @mouseMenuClickCB="mouseMenuClickCB"
      ></MouseDialog>
    </Transition>
  </div>
</template>

<script setup lang="ts">
  import useNamespace from '@/hooks/use-namespace'
  import { ref, computed, provide, onBeforeMount } from 'vue'
  import WinHeader from './winHeader.vue'
  import WinRow from './winRow.vue'
  import MouseDialog from './mouseDialog.vue'
  import deepClone from '@/hooks/deepClone'
  const columns = ref()
  const props = defineProps<{
    // 高亮显示
    highlight?: boolean
    // 列宽度可更改
    resizable?: boolean
    // 表格限制宽度
    width?: number
    // 表格限制高度
    height?: number
    // 是否需要斑马纹
    stripe?: boolean
    // 表格内容对其方式
    direction?: string
    // 需要作为vfor的key绑定
    keyName: string
    // 表格边框
    border?: boolean
    // 是否需要索引
    index?: boolean
    // 索引的列宽
    indexWidth?: number
    // 用于渲染表格的数据
    data: Array<any>
    // 用于渲染列的规则
    columns: Array<{
      // 用于绑定data里的数据字段名
      field: string
      // 用于渲染在列头上的列明
      listed: string
      // 列宽度
      width?: number
    }>
    // 右键菜单需要的数据
    mouseMenu?: {
      // 需要显示在第一行的字段名
      mouseData: string
      title?: boolean
      buttons: Array<{
        // 按钮标识
        id: string
        // 可选按钮图标
        icon?: string
        // 按钮文字提示
        text: string
      }>
    }
  }>()
  const un = useNamespace('table')
  const mouseDialog = ref()
  const emit = defineEmits(['loading', 'dialogCB'])

  provide('index', props.index)
  provide('border', props.border)
  provide('direction', props.direction)
  provide('stripe', props.stripe)
  provide('resizable', props.resizable)
  provide('highlight', props.highlight)
  provide('needIndex', props.index)
  onBeforeMount(() => {
    columns.value = deepClone(props.columns)
    provide('columns', columns.value)
  })
  const tableStyle = computed(() => {
    const style: { [x: string]: string } = {}
    if (props.width && props.width > 100) {
      style.width = props.width + 'px'
    }
    if (props.height && props.height > 100) {
      style.height = props.height + 'px'
    }
    return style
  })
  const rightMenu = (e: MouseEvent, row: any) => {
    let event = e || window.event
    e.preventDefault ? e.preventDefault() : (event.returnValue = false)
    let x = event.clientX
    let y = event.clientY
    mouseDialog.value.open(x, y, row)
  }
  const mouseMenuClickCB = (id: string, row: any) => {
    emit('dialogCB', id, row)
  }
  const changeWidth = (index: number, flag: boolean) => {
    if (flag) {
      columns.value[index].width -= 10
    } else {
      columns.value[index].width += 10
    }
  }
</script>

<style lang="scss" scoped>
  .table-container {
    overflow: auto;

    .--win-table {
      width: 100%;
      padding: 0;
      box-sizing: border-box;
      color: $text-color;
    }
    .scale-enter-active {
      transition: all 0.3s;
      transform-origin: 0px 0px;
      // position: fixed;
    }

    .scale-leave-active {
      transition: all 0.5s;
      transform-origin: 0px 0px;
      // position: fixed;
    }

    .scale-enter-from,
    .scale-leave-to {
      // position: fixed;
      // top: 74vh;
      // left: 34vw;
      transform: scale(0.2);
      opacity: 0;
    }
  }
</style>
